"""
原型模式（Prototype Pattern）是用于创建重复的对象，同时又能保证性能。
这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式之一。
这种模式是实现了一个原型接口，该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时，则采用这种模式。
意图：
    使用原型实例指定要创建对象的种类，并通过拷贝这些原型创建新的对象。
适用性：
    在运行时动态建立和删除原型。
结构：
    原型接口（Prototype Interface）：定义一个用于克隆自身的接口，通常包括一个 clone() 方法。
    具体原型类（Concrete Prototype）：实现原型接口的具体类，负责实际的克隆操作。这个类需要实现 clone() 方法，通常使用浅拷贝或深拷贝来复制自身。
    客户端（Client）：使用原型实例来创建新的对象。客户端调用原型对象的 clone() 方法来创建新的对象，而不是直接使用构造函数。
"""
import copy


# 原型接口
class Prototype:
    def __init__(self):
        self._object = {}

    def register_object(self, name, obj):
        self._object[name] = obj

    def unregister_object(self, name):
        del self._object[name]

    def clone(self, name, **attrs):
        obj = copy.deepcopy(self._object.get(name))
        obj.__dict__.update(attrs)
        return obj


# 具体原型类
class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model

    def __str__(self):
        return f'{self.make} {self.model}'


if __name__ == '__main__':
    car_prototype = Prototype()
    # 注册原型
    car_prototype.register_object('sports_car', Car('Ferrari', '488'))
    # 克隆修改
    new_car = car_prototype.clone('sports_car', model='488GTB')
    print(new_car)
    # 克隆
    another_car = car_prototype.clone('sports_car')
    print(another_car)
